﻿using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using System.Runtime.Intrinsics.X86;
using System.Security.Claims;
using System.Threading.Tasks;

namespace Identity框架.Controllers
{
    /// <summary>
    /// 用户操作接口
    /// </summary>
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class User : ControllerBase
    {
        private readonly UserManager<MyUser> _userManager;
        private readonly RoleManager<MyRole> _roleManager;
        private readonly IWebHostEnvironment _webHostEnvironment;
        public User(UserManager<MyUser> userManager, RoleManager<MyRole> roleManager, IWebHostEnvironment webHostEnvironment)
        {
            _userManager = userManager;
            _roleManager = roleManager;
            _webHostEnvironment = webHostEnvironment;
        }

        /// <summary>
        /// 添加用户
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public async Task<ActionResult> AddDat()
        {
            // 创建角色
            var roleResult = await _roleManager.FindByNameAsync("Admin");
            if (roleResult == null)
            {
                MyRole myRole = new MyRole() { Name = "Admin" };
                var rr = await _roleManager.CreateAsync(myRole);
                if (!rr.Succeeded) return BadRequest("角色创建失败");
            }

            // 创建用户
            MyUser user1 = await _userManager.FindByNameAsync("yhs");
            if (user1 == null)
            {
                MyUser myUser = new MyUser()
                {
                    UserName = "yhs",
                    Email = "1578139612@qq.com"
                };

                // 创建用户并设置密码
                var createResult = await _userManager.CreateAsync(myUser, "123456");
                if (!createResult.Succeeded) return BadRequest(createResult.Errors);



                // ================= 关联 AspNetUserTokens 的关键部分 =================
                // 1. 生成访问令牌
                string accessToken = GenerateAccessToken(user1);


                // 2. 存储令牌到 AspNetUserTokens 表
                await _userManager.SetAuthenticationTokenAsync(
                    user: user1,
                    loginProvider: "CustomProvider", // 自定义提供者名称
                    tokenName: "AccessToken",
                    tokenValue: accessToken
                );

                // 3. 可选：生成并存储刷新令牌
                string refreshToken = GenerateRefreshToken();
                await _userManager.SetAuthenticationTokenAsync(
                    user1,
                    "CustomProvider",
                    "RefreshToken",
                    refreshToken
                );
            }

            // 将用户添加到角色
            if (!await _userManager.IsInRoleAsync(user1, "Admin"))
            {
                var addRoleResult = await _userManager.AddToRoleAsync(user1, "Admin");
                if (!addRoleResult.Succeeded) return BadRequest(addRoleResult.Errors);
            }



            return Ok(new
            {
                Message = "用户和角色创建成功",
                UserId = user1.Id,
                AccessToken = "null" // 返回生成的令牌
            });
        }

        // 生成访问令牌的辅助方法
        private string GenerateAccessToken(MyUser user)
        {
            // 实际项目中应使用更安全的方式如JWT
            // 这里使用简化示例
            return $"{user.UserName}-{Guid.NewGuid()}-{DateTime.UtcNow.Ticks}";
        }

        // 生成刷新令牌的辅助方法
        private string GenerateRefreshToken()
        {
            return Guid.NewGuid().ToString("N") + DateTime.UtcNow.Ticks;
        }

        /// <summary>
        /// 检查账户
        /// </summary>
        /// <param name="requitPwd">请求的用户和密码</param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ActionResult> CheckPwd(RequitPwd requitPwd)
        {
            string userName = requitPwd.userName;
            string userPwd = requitPwd.userPwd;
            var user2 = await _userManager.FindByNameAsync(userName);
            if (user2 == null)
            {
                if (_webHostEnvironment.IsDevelopment())
                {
                    return BadRequest($"用户名不存在{userName}");
                }
                else
                {
                    return BadRequest($"用户名或密码不存在");
                }
            }
            if (await _userManager.IsLockedOutAsync(user2))
            {
                return BadRequest($"密码已锁定" + user2.LockoutEnd);

            }
            var result = await _userManager.CheckPasswordAsync(user2, userPwd);
            if (result)
            {
                await _userManager.ResetAccessFailedCountAsync(user2);

                return Ok("登录成功");
            }
            else
            {
                await _userManager.AccessFailedAsync(user2);
                return BadRequest($"登录失败{user2.AccessFailedCount}次");
            }


        }

        /// <summary>
        /// 生成token
        /// </summary>
        /// <param name="name">用户名</param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ActionResult> SendToken(string name)
        {
            var user2 = await _userManager.FindByNameAsync(name);
            if (user2 == null)
            {
                if (_webHostEnvironment.IsDevelopment())
                {
                    return BadRequest($"用户名不存在{name}");
                }
                else
                {
                    return BadRequest($"用户名或密码不存在");
                }
            }
            var token = await _userManager.GeneratePasswordResetTokenAsync(user2);
            // 2. 存储令牌到 AspNetUserTokens 表
            await _userManager.SetAuthenticationTokenAsync(
                user: user2,
                loginProvider: "CustomProvider", // 自定义提供者名称
                tokenName: "AccessToken",
                tokenValue: token
            );
            await _userManager.UpdateAsync(user2);

            return Ok($"验证码是{token}");
        }

        /// <summary>
        /// 改变密码
        /// </summary>
        /// <param name="name">用户名</param>
        /// <param name="token">token</param>
        /// <param name="newPwd">新密码</param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ActionResult> ChangedPwd(string name, string token, string newPwd)
        {
            var user2 = await _userManager.FindByNameAsync(name);
            if (user2 == null)
            {
                if (_webHostEnvironment.IsDevelopment())
                {
                    return BadRequest($"用户名不存在{name}");
                }
                else
                {
                    return BadRequest($"用户名或密码不存在");
                }
            }
            var result = await _userManager.ResetPasswordAsync(user2, token, newPwd);
            if (result.Succeeded)
            {
                await _userManager.ResetAccessFailedCountAsync(user2);

                return Ok("重置密码成功");
            }
            else
            {
                await _userManager.AccessFailedAsync(user2);
                return BadRequest($"重置失败");
            }

        }

        /// <summary>
        /// 删除用户及角色
        /// </summary>
        /// <param name="name">用户名</param>
        /// <returns></returns>
        [HttpPost]
        public async Task<ActionResult> DeleteData(string name)
        {
            // 查找用户
            var user = await _userManager.FindByNameAsync(name);
            if (user == null)
            {
                return BadRequest("用户名不存在");
            }

            // 获取用户的所有角色
            var userRoles = await _userManager.GetRolesAsync(user);

            // 先删除用户的所有角色关系
            if (userRoles.Any())
            {
                var removeResult = await _userManager.RemoveFromRolesAsync(user, userRoles);
                if (!removeResult.Succeeded)
                {
                    return BadRequest(removeResult.Errors);
                }
            }

            // 删除用户
            var deleteResult = await _userManager.DeleteAsync(user);
            if (!deleteResult.Succeeded)
            {
                return BadRequest(deleteResult.Errors);
            }

            // 删除这些角色（如果不再被其他用户使用）
            foreach (var roleName in userRoles)
            {
                var role = await _roleManager.FindByNameAsync(roleName);
                if (role != null)
                {
                    // 检查角色是否还被其他用户使用
                    var usersInRole = await _userManager.GetUsersInRoleAsync(roleName);
                    if (usersInRole.Count == 0) // 如果角色没有其他用户使用
                    {
                        await _roleManager.DeleteAsync(role);
                    }
                }
            }

            return Ok($"删除成功 {user.UserName} 及其关联的未使用角色");
        }


    }
}
